package com.xzx.redislock.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.Duration;

@Component
public class RedisLockUtil {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 上锁
     * @param lockKey 加锁的key
     * @param timeStamp 时间戳  当前时间+超时时间
     * @return
     */
    public Boolean onLock(String lockKey,String timeStamp){
        //上锁
        if (stringRedisTemplate.opsForValue().setIfAbsent(lockKey,timeStamp)){
            //setIfAbsent() 作用相当于 redis命令 SETNX
            //添加key时,key不存在存储redis  如果 key存在 存储redis失败
            return true;
        }
        stringRedisTemplate.opsForValue().setIfAbsent(lockKey,timeStamp,Duration.ofSeconds(10));
        //设置失败,获得锁失败
        // 1.判断锁超时 - 防止原来的操作异常，没有运行解锁操作 ，防止死锁
        String currentValue = stringRedisTemplate.opsForValue().get(lockKey);
        //释放锁失败 并且 锁超时
        if (StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){
            //getAndSet();一次只有一个线程执行
            String preLockValue = stringRedisTemplate.opsForValue().getAndSet(lockKey,timeStamp);
            if (!StringUtils.isEmpty(preLockValue) && preLockValue.equals(currentValue)){
                return true;
            }
        }
        return false;
    }

    /**
     * 释放锁
     * @param lockKey
     * @param timeStamp
     */
    public void releaseLock(String lockKey,String timeStamp){
        try {
            String currentValue = stringRedisTemplate.opsForValue().get(lockKey);
            if (!StringUtils.isEmpty(currentValue) && currentValue.equals(timeStamp)){
                //删除锁状态
                stringRedisTemplate.opsForValue().getOperations().delete(lockKey);
            }
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("锁释放失败");
        }



    }
}
